package com.liaowei.comment.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liaowei.comment.mapper.PostCommentMapper;
import com.liaowei.comment.model.param.PostCommentParam;
import com.liaowei.comment.openfeign.PostClient;
import com.liaowei.comment.openfeign.UserClient;
import com.liaowei.comment.service.PostCommentService;
import com.liaowei.common.BaseResponse;
import com.liaowei.common.Constants;
import com.liaowei.common.ErrorCode;
import com.liaowei.exception.CustomerException;
import com.liaowei.model.domain.PostComment;
import com.liaowei.model.param.PostCommentStatusParam;
import com.liaowei.model.param.PostUserParam;
import com.liaowei.model.param.QueryManagePostCommentParam;
import com.liaowei.model.vo.PostCommentVO;
import com.liaowei.model.vo.UserVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @author LindaMan
* @description 针对表【wy_post_comment(帖子-评论表)】的数据库操作Service实现
* @createDate 2023-05-09 15:26:25
*/
@Service
@RequiredArgsConstructor
public class PostCommentServiceImpl extends ServiceImpl<PostCommentMapper, PostComment>
    implements PostCommentService{

    private final PostCommentMapper postCommentMapper;
    private final PostClient postClient;
    private final UserClient userClient;

    // 校验用户是否认证
    public void matchUser(Long userId, Long loginId) {
        if (!loginId.equals(userId)) {
            throw new CustomerException(Constants.PARAM_ERROR, "请先认证");
        }
    }

    // 根据id获取用户别名
    public String getNicknameByUserId(Long userId) {
        BaseResponse<UserVO> res = userClient.getById(userId);
        if (res.getCode() == 1) {
            return res.getData().getNickname();
        }
        return "小鲲";
    }

    // 根据id获取用户头像
    public String getAvatarByUserId(Long userId) {
        BaseResponse<UserVO> res = userClient.getById(userId);
        if (res.getCode() == 1) {
            return res.getData().getAvatar();
        }
        return "小鲲";
    }

    // 将articleComment转换为articleCommentVO
    public PostCommentVO toPostCommentVO(PostComment comment) {
        PostCommentVO vo = new PostCommentVO();

        Long replyId = comment.getReplyId(); // 获取replyId
        // 对象复制
        BeanUtil.copyProperties(comment, vo);
        // 封装其他属性
        // nickname
        vo.setNickname(getNicknameByUserId(comment.getUserId()));

        // avatar
        vo.setAvatar(getAvatarByUserId(comment.getUserId()));

        // replyName
        // 判断回复类型
        Integer replyType = comment.getReplyType();
        if (replyType == Constants.COMMENT_REPLY_TYPE_CONTENT) {
            // 回复内容
            vo.setReplyName("");
        } else {
            // 回复用户
            vo.setReplyName(getNicknameByUserId(replyId));
        }

        // 返回结果
        return vo;
    }


    /**
     * 根据帖子id删除帖子的评论
     * @param postId 帖子id
     * @param userId 用户id
     * @return 提示信息
     */
    @Transactional
    @Override
    public String deletePostCommentByIdAndUserId(Long postId, Long userId) {
        // 获取当前认证的id
        Long loginId = Long.parseLong(StpUtil.getLoginId().toString());

        // 判断是否是管理员继续操作
        if (userId != 1){ // 不是管理员
            // 判断当前要删除的是不是自己的评论
            matchUser(userId, loginId);
        }

        // 删除文章评论
        LambdaQueryWrapper<PostComment> wrapper = Wrappers.lambdaQuery(PostComment.class)
                .eq(PostComment::getPostId, postId);
        try {
            postCommentMapper.delete(wrapper);
        }catch (Exception e){
            throw new CustomerException(ErrorCode.SYSTEM_ERROR);
        }

        return "删除成功";
    }

    /**
     * 后台-分页查询评论列表
     * @param pageNum 当前页
     * @param pageSize 分页大小
     * @return IPage<PostComment>
     */
    @Override
    public IPage<PostCommentVO> searchManagePage(int pageNum, int pageSize) {
        // 构造分页构造器
        IPage<PostComment> page = new Page<>(pageNum,pageSize);

        // 分页查询
        LambdaUpdateWrapper<PostComment> wrapper = Wrappers.lambdaUpdate(PostComment.class)
                .orderByDesc(PostComment::getCreateTime);
        postCommentMapper.selectPage(page,wrapper);

        // 封装voPage
        IPage<PostCommentVO> voPage = new Page<>();
        // 对象复制
        BeanUtil.copyProperties(page, voPage, "records");
        // records封装
        List<PostCommentVO> voList = page.getRecords().stream()
                .map(this::toPostCommentVO).collect(Collectors.toList());
        voPage.setRecords(voList);

        return voPage;
    }

    /**
     * 分页查询评论列表
     * @param commentParam 分页条件参数
     * @return IPage<PostCommentVO>
     */
    @Override
    public IPage<PostCommentVO> searchPage(QueryManagePostCommentParam commentParam) {
        // 构造分页构造器
        IPage<PostComment> page = new Page<>(commentParam.getPageParam().getPageNum(),
                commentParam.getPageParam().getPageSize());

        // 构造查询构造器
        LambdaUpdateWrapper<PostComment> pageWrapper = Wrappers.lambdaUpdate(PostComment.class)
                .eq(PostComment::getPostId, commentParam.getPostId())
                .orderByDesc(PostComment::getCreateTime);

        // 分页查询
        postCommentMapper.selectPage(page, pageWrapper);

        // 封装voPage
        IPage<PostCommentVO> voPage = new Page<>();
        // 对象复制
        BeanUtil.copyProperties(page, voPage, "records");
        // records封装
        List<PostCommentVO> voList = page.getRecords().stream()
                .map(this::toPostCommentVO).collect(Collectors.toList());
        voPage.setRecords(voList);

        return voPage;
    }

    /**
     * 删除评论
     * @param commentId 评论id
     * @param postId 帖子id
     * @param userId 用户id
     * @return
     */
    @Transactional
    @Override
    public String deletePostComment(Long commentId, Long postId, Long userId) {
        // 获取当前认证的id
        Long loginId = Long.parseLong(StpUtil.getLoginId().toString());

        // 判断是否是管理员继续操作
        if (userId != 1){ // 不是管理员
            // 判断当前要删除的是不是自己的评论
            matchUser(userId, loginId);
        }

        // 修改articleUser
        PostCommentStatusParam param = new PostCommentStatusParam();
        param.setPostId(postId);
        param.setUserId(userId);
        param.setCommentStatus(0);
        postClient.commentStatus(param);

        // 删除评论
        postCommentMapper.deleteById(commentId);

        return "删除成功";
    }

    /**
     * 评论帖子
     * @param commentParam 评论参数
     * @return 提示信息
     */
    @Transactional
    @Override
    public String savePostComment(PostCommentParam commentParam) {
        // 获取当前认证的id
        Long loginId = Long.parseLong(StpUtil.getLoginId().toString());
        // 获取回复id
        Long replyId = commentParam.getReplyId();
        // 获取帖子id
        Long postId = commentParam.getPostId();

        // 对评论人id进行二次校验
        Long userId = commentParam.getUserId(); // 评论人id
        matchUser(userId, loginId);

        // 对回复类型进行判断
        Integer replyType = commentParam.getReplyType();
        if (replyType == Constants.COMMENT_REPLY_TYPE_CONTENT) {
            // 回复内容
            if (!Objects.equals(replyId, postId))
                throw new CustomerException(Constants.PARAM_ERROR, "请回复合法对象");
        } else if (replyType == Constants.COMMENT_REPLY_TYPE_USER) {
            // 回复用户
            // 再查询是否已经有用户评论过
            LambdaQueryWrapper<PostComment> replyWrapper = Wrappers.lambdaQuery(PostComment.class)
                    .eq(PostComment::getUserId, replyId)
                    .eq(PostComment::getPostId, postId);
            Long count = postCommentMapper.selectCount(replyWrapper);
            if (count < 1)
                throw new CustomerException(Constants.PARAM_ERROR, "请回复合法对象");
        } else {
            throw new CustomerException(Constants.PARAM_ERROR, "请回复合法对象");
        }

        // 添加文章评论
        PostComment postComment = new PostComment();
        postComment.setPostId(postId);
        postComment.setContent(commentParam.getContent());
        postComment.setUserId(userId);
        postComment.setReplyId(replyId);
        postComment.setReplyType(commentParam.getReplyType());
        postComment.setParentId(commentParam.getParentId());
        try {
            // 保存postUser 评论状态
            PostUserParam postUserParam = new PostUserParam();
            postUserParam.setPostId(postId);
            postUserParam.setUserId(userId);
            postUserParam.setCommentStatus(1);
            postClient.savePostUser(postUserParam);

            // 保存评论
            postCommentMapper.insert(postComment);
        } catch (Exception e) {
            throw new CustomerException(ErrorCode.SYSTEM_ERROR);
        }

        return "评论成功";
    }
}




